package com.jesse.observer;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.jesse.base.ManagerBase;
import com.jesse.dao.UpdateEvent;
import com.jesse.util.ViewUtil;

/**
 * 通知总线
 * @author jesse
 *
 */
public class ObserverBus extends ManagerBase{

	/**
	 * 使用嵌套的HashMap，结构为map<eventKey, List<map<pbserverKey, UpdateEvent>>>
	 */
	private Map<String, List<Map<String, UpdateEvent>>> observerMap = new HashMap<String, List<Map<String, UpdateEvent>>>();
	
	private static volatile ObserverBus instance;
	
	private ObserverBus() {}
	
	public static ObserverBus getInstance() {
		if (instance == null) {
			synchronized (ObserverBus.class) {
				if (instance == null) {
					instance = new ObserverBus();
				}
			}
		}
		return instance;
	}
	

	@Override
	public void releaseManager() {
		resetPool();
		instance = null;
	}

	@Override
	public void resetPool() {
		observerMap.clear();
	}
	
	/**
	 * 注册观察者
	 * 
	 * @param eventKey			事件Key值，妥善保管该Key值，相同事件应该对应相同的Key值
	 * @param observerKey		注册该事件的观察者Key值，可以使用acitivty的名称得，必须具备唯一性，相同的key值会被直接覆盖
	 * @param observable		{@link UpdateEvent} 通知接口
	 */
	public void registerEvent(String eventKey, String observerKey, UpdateEvent updateEvent) {
		synchronized (ObserverBus.class) {
			List<Map<String, UpdateEvent>> list;
			if (observerMap.get(eventKey) == null) {
				list = new ArrayList<Map<String,UpdateEvent>>();
			} else {
				list = observerMap.get(eventKey);
			}
			Map<String, UpdateEvent> map = new HashMap<String, UpdateEvent>();
			map.put(observerKey, updateEvent);
			list.add(map);
			observerMap.put(eventKey, list);
		}
	}
	
	/**
	 * 注销观察者
	 * @param eventKey			事件Key值，妥善保管该Key值，相同事件应该对应相同的Key值
	 * @param observerKey		注册该事件时使用的观察者Key值，
	 */
	public synchronized void unregistEvent(String eventKey, String observerKey) {
		synchronized (ObserverBus.class) {
			if (observerMap.isEmpty()) {
				return;
			}
			List<Map<String, UpdateEvent>> list;
			if (eventKey == null) {
				throw new NullPointerException("Event key is null ");
			} 
			if (eventKey.isEmpty()) {
				throw new IllegalAccessError("The eventkeyey can not be empty!");
			}
			if (observerMap.get(eventKey) == null) {
				return;
			} else {
				list = observerMap.get(eventKey);
			}
			for (Map<String, UpdateEvent> item : list) {
				Iterator iterator = item.keySet().iterator();
				while(iterator.hasNext()){ 
					if (((String)iterator.next()).equals(observerKey)) {
						iterator.remove();
					}
				}  
			}
		}
	}
	
	/**
	 * 广播事件
	 * @param eventkey		注册事件时，使用的事件Key
	 * @param event			
	 */
	public synchronized void updateEvent(String eventkey, Object event) {
		synchronized (ObserverBus.class) {
			if (observerMap.isEmpty()) {
				return;
			}
			if (observerMap.get(eventkey) == null) {
				ViewUtil.Debug("Do not have this " + eventkey + " event key! Are you registe it in function registerEvent ? ");
				return;
			} 
			if (eventkey == null) {
				throw new NullPointerException("Event key is null ");
			}
			if (eventkey.isEmpty()) {
				throw new NullPointerException("The eventkeyey can not be empty!");
			}
			List<Map<String, UpdateEvent>> list = observerMap.get(eventkey);
			if (list == null) {
				return;
			}
			for (Map<String, UpdateEvent> item : list) {
				Iterator iterator = item.entrySet().iterator();
				while(iterator.hasNext()){  
					Map.Entry entry = (Map.Entry) iterator.next();
					ViewUtil.Debug("发送事件" +eventkey +"至"+ entry.getKey());
					((UpdateEvent)entry.getValue()).update(event);
				}  
			}
		}
	}
}
